package com.dbflow5.migration;

import com.dbflow5.database.DatabaseWrapper;
import com.dbflow5.query.BaseQueriable;
import com.dbflow5.query.OperatorGroup;
import com.dbflow5.query.SQLOperator;
import com.dbflow5.query.SQLite;

import java.util.Arrays;

/**
 * Description: Provides a simple way to update a table's field or fields quickly in a migration.
 * It ties an SQLite [com.dbflow5.sql.language.Update]
 * to migrations whenever we want to batch update tables in a structured manner.
 */
public class UpdateTableMigration<T> extends BaseMigration {
    private Class<T> table;

    public UpdateTableMigration(Class<T> table){
        this.table = table;
    }

    /**
     * Builds the conditions for the WHERE part of our query
     *
     * @return OperatorGroup.nonGroupingClause()
     */
    private OperatorGroup whereOperatorGroup() {
        return OperatorGroup.nonGroupingClause();
    }

    /**
     * The conditions to use to set fields in the update query
     *
     * @return OperatorGroup.nonGroupingClause()
     */
    private OperatorGroup setOperatorGroup(){
        return OperatorGroup.nonGroupingClause();
    }

    /**
     * BaseQueriable
     *
     * @return SQLite.update
     */
    public BaseQueriable<T> updateStatement(){
        return SQLite.update(table)
                .set(setOperatorGroup())
                .where(whereOperatorGroup());
    }

    /**
     * This will append a condition to this migration. It will execute each of these in succession with the order
     * that this is called.
     *
     * @param conditions The conditions to append
     * @return this
     */
    public UpdateTableMigration<T> set(SQLOperator... conditions) {
        setOperatorGroup().andAll(Arrays.asList(conditions));
        return this;
    }

    /**
     * UpdateTableMigration
     *
     * @param conditions conditions
     * @return this
     */
    public UpdateTableMigration<T> where(SQLOperator... conditions) {
        whereOperatorGroup().andAll(Arrays.asList(conditions));
        return this;
    }

    /**
     * migrate
     *
     * @param database database
     */
    @Override
    public void migrate(DatabaseWrapper database) {
        updateStatement().execute(database);
    }
}
